package com.restaurant.application.indexes.accumulatelist.mysql;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.nebutown.base.Unit;
import com.nebutown.description.data.SortSpec;
import com.nebutown.generation.basictype.UID;
import com.nebutown.supporthome.AbstractIndex;

import java.sql.ResultSet;
import java.util.List;
import java.util.Map;

public class AccumulateListTableImpl extends AbstractIndex<AccumulateListTableCriteria, AccumulateListTableBean> {
    
    @Override
    public String getTableName() {
        return "" + getConnectionName() + ".ACCUMULATELISTTABLE";
    }
    
    @Override
    public AccumulateListTableBean newBean() {
        return new AccumulateListTableBean();
    }
    
    @Override
    public AccumulateListTableCriteria newCriteria() {
        return new AccumulateListTableCriteria();
    }
    
    @Override
    public List<String> getFieldNames() {
        return Lists.newArrayList(
                "accumulate",
                "customerName",
                "createTime",
                "points",
                "type",
                "detail",
                "action",
                "customerId",
                "phone",
                "customerUID");
    }
    
    @Override
    public List<String> getDateFields() {
        return Lists.newArrayList(
                "createTime",
                "points");
    }
    
    @Override
    public List<String> getDoubleFields() {
        return Lists.newArrayList(
                "");
    }
    
    @Override
    public Map<String, String> getFieldLabels() {
        return ImmutableMap.<String, String>builder()
                .put("customerName", "用户名字")
                .put("createTime", "时间")
                .put("points", "积分")
                .put("type", "类型")
                .put("detail", "积分来源详情基元")
                .put("action", "积分创建描述")
                .put("customerId", "客户Id")
                .put("phone", "手机号码")
                .build();
    }
    
    @Override
    public List<String> getContributors() {
        return Lists.newArrayList(
                "com.restaurant.application.accumulate.accumulate",
                 "com.restaurant.application.customer.Customer");
    }
    
    @Override
    public AccumulateListTableBean fakeBean() {
        AccumulateListTableBean bean = new AccumulateListTableBean();

        bean.setAccumulate(UID.recover("A 3214649870806014984 looooong string"));
        bean.setCustomerName("A 8181697969707336963 looooong string");
        bean.setCreateTime(-1537739658L);
        bean.setPoints(-1584619647L);
        bean.setType("A -4971006458259157869 looooong string");
        bean.setDetail("A 1931274956399895740 looooong string");
        bean.setAction("A 2380647887352666376 looooong string");
        bean.setCustomerId("A -642272311886427928 looooong string");
        bean.setPhone("A 6879357800277279847 looooong string");
        bean.setCustomerUID(UID.recover("A 5801399326453824113 looooong string"));
        return bean;
    }
    
    @Override
    public String getCreateTableStatement() {
        StringBuilder buf = new StringBuilder();
        
        buf.append("CREATE TABLE IF NOT EXISTS " + getConnectionName() + ".ACCUMULATELISTTABLE (\n");
        buf.append("    RECORD_ID BIGINT AUTO_INCREMENT,\n");
        buf.append("    ACCUMULATE CHAR(128) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,\n");
        buf.append("    CUSTOMERNAME VARCHAR(255),\n");
        buf.append("    CREATETIME BIGINT,\n");
        buf.append("    POINTS BIGINT,\n");
        buf.append("    TYPE VARCHAR(255),\n");
        buf.append("    DETAIL VARCHAR(255),\n");
        buf.append("    ACTION VARCHAR(255),\n");
        buf.append("    CUSTOMERID VARCHAR(255),\n");
        buf.append("    PHONE VARCHAR(255),\n");
        buf.append("    CUSTOMERUID CHAR(128) CHARACTER SET latin1 COLLATE latin1_general_cs NOT NULL,\n");
        buf.append("PRIMARY KEY (RECORD_ID)) CHARACTER SET  = utf8mb4 COLLATE = utf8mb4_bin");
        return buf.toString();
    }
    
    @Override
    public String getInsertDataStatement(AccumulateListTableBean data) {
        StringBuilder buf = new StringBuilder();
        
        buf.append("INSERT INTO " + getConnectionName() + ".ACCUMULATELISTTABLE (\n    ");
        buf.append("    ACCUMULATE, CUSTOMERNAME, CREATETIME, POINTS, TYPE, DETAIL, ACTION, CUSTOMERID, PHONE, CUSTOMERUID");
        buf.append(") VALUES (");
        buf.append("    '" + cut(data.getAccumulate(), 128) + "', '" + cut(data.getCustomerName(), 255) + "', " + data.getCreateTime() + ", " + data.getPoints() + ", '" + cut(data.getType(), 255) + "', '" + cut(data.getDetail(), 255) + "', '" + cut(data.getAction(), 255) + "', '" + cut(data.getCustomerId(), 255) + "', '" + cut(data.getPhone(), 255) + "', '" + cut(data.getCustomerUID(), 128) + "'");
        buf.append(")");
        return buf.toString();
    }
    
    @Override
    public String getDeleteRowsStatement(Long rowId) {
        return "DELETE FROM " + getConnectionName() + ".ACCUMULATELISTTABLE WHERE  RECORD_ID = " + rowId;
    }
    
    @Override
    public String getLocalUpdateStatement(AccumulateListTableBean data) {
        StringBuilder buf = new StringBuilder();
        StringBuilder sep = new StringBuilder();
        
        boolean hasData = false;
        
        buf.append("UPDATE " + getConnectionName() + ".ACCUMULATELISTTABLE \n");
        buf.append("   SET ");
        if(data.getAccumulate() != null) {
            buf.append(sep.toString() + "\n      ACCUMULATE = '" + cut(data.getAccumulate(), 128) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCustomerName() != null) {
            buf.append(sep.toString() + "\n      CUSTOMERNAME = '" + cut(data.getCustomerName(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCreateTime() != null) {
            buf.append(sep.toString() + "\n      CREATETIME = " + data.getCreateTime() + "");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getPoints() != null) {
            buf.append(sep.toString() + "\n      POINTS = " + data.getPoints() + "");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getType() != null) {
            buf.append(sep.toString() + "\n      TYPE = '" + cut(data.getType(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getDetail() != null) {
            buf.append(sep.toString() + "\n      DETAIL = '" + cut(data.getDetail(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getAction() != null) {
            buf.append(sep.toString() + "\n      ACTION = '" + cut(data.getAction(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCustomerId() != null) {
            buf.append(sep.toString() + "\n      CUSTOMERID = '" + cut(data.getCustomerId(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getPhone() != null) {
            buf.append(sep.toString() + "\n      PHONE = '" + cut(data.getPhone(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCustomerUID() != null) {
            buf.append(sep.toString() + "\n      CUSTOMERUID = '" + cut(data.getCustomerUID(), 128) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(!hasData) return "";
        
        hasData = false;
        buf.append(" WHERE TRUE\n");
        if(data.getAccumulate() != null) {
            buf.append("    AND ACCUMULATE = '" + data.getAccumulate() + "'\n");
            hasData = true;
        }
        if(data.getCustomerUID() != null) {
            buf.append("    AND CUSTOMERUID = '" + data.getCustomerUID() + "'\n");
            hasData = true;
        }
        if(!hasData) return "";
        
        return buf.toString();
    }
    
    @Override
    public String getUpdateByIdStatement(AccumulateListTableBean data) {
        StringBuilder buf = new StringBuilder();
        StringBuilder sep = new StringBuilder();
        
        boolean hasData = false;
        
        buf.append("UPDATE " + getConnectionName() + ".ACCUMULATELISTTABLE \n");
        buf.append("   SET ");
        if(data.getAccumulate() != null) {
            buf.append(sep.toString() + "\n      ACCUMULATE = '" + cut(data.getAccumulate(), 128) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCustomerName() != null) {
            buf.append(sep.toString() + "\n      CUSTOMERNAME = '" + cut(data.getCustomerName(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCreateTime() != null) {
            buf.append(sep.toString() + "\n      CREATETIME = " + data.getCreateTime() + "");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getPoints() != null) {
            buf.append(sep.toString() + "\n      POINTS = " + data.getPoints() + "");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getType() != null) {
            buf.append(sep.toString() + "\n      TYPE = '" + cut(data.getType(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getDetail() != null) {
            buf.append(sep.toString() + "\n      DETAIL = '" + cut(data.getDetail(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getAction() != null) {
            buf.append(sep.toString() + "\n      ACTION = '" + cut(data.getAction(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCustomerId() != null) {
            buf.append(sep.toString() + "\n      CUSTOMERID = '" + cut(data.getCustomerId(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getPhone() != null) {
            buf.append(sep.toString() + "\n      PHONE = '" + cut(data.getPhone(), 255) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(data.getCustomerUID() != null) {
            buf.append(sep.toString() + "\n      CUSTOMERUID = '" + cut(data.getCustomerUID(), 128) + "'");
            hasData = true;
            sep.setLength(0);
            sep.append(",");
        }
        if(!hasData) return "";
        
        hasData = false;
        buf.append(" WHERE RECORD_ID = " + data.getRecordId());
        return buf.toString();
    }
    
    @Override
    public AccumulateListTableBean extractLine(ResultSet resultSet) throws Exception {
        AccumulateListTableBean result = new AccumulateListTableBean();
        
        result.setRecordId(resultSet.getLong("RECORD_ID"));
        result.setAccumulate(UID.recover(resultSet.getString("accumulate")));
        result.setCustomerName(resultSet.getString("customerName"));
        result.setCreateTime(resultSet.getLong("createTime"));
        result.setPoints(resultSet.getLong("points"));
        result.setType(resultSet.getString("type"));
        result.setDetail(resultSet.getString("detail"));
        result.setAction(resultSet.getString("action"));
        result.setCustomerId(resultSet.getString("customerId"));
        result.setPhone(resultSet.getString("phone"));
        result.setCustomerUID(UID.recover(resultSet.getString("customerUID")));
        return result;
    }
    
    @Override
    public String getWherePart(AccumulateListTableCriteria criteria, SortSpec sort) {
        StringBuilder buf = new StringBuilder(" TRUE ");
        
        criteria.setCustomerNameLike(searchString(criteria.getCustomerNameLike()));
        criteria.setTypeLike(searchString(criteria.getTypeLike()));
        criteria.setDetailLike(searchString(criteria.getDetailLike()));
        criteria.setActionLike(searchString(criteria.getActionLike()));
        criteria.setCustomerIdLike(searchString(criteria.getCustomerIdLike()));
        criteria.setPhoneLike(searchString(criteria.getPhoneLike()));
        
        if(criteria.getRecordId() != null) {
            buf.append("    AND RECORD_ID = " + criteria.getRecordId());
        }
        if(criteria.getAccumulateEquals() != null) {
            buf.append("    AND ACCUMULATE = '" + criteria.getAccumulateEquals() + "'");
        }
        if(criteria.getAccumulateNotEquals() != null) {
            buf.append("    AND ACCUMULATE != '" + criteria.getAccumulateNotEquals() + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getCustomerNameEquals())) {
            buf.append("    AND CUSTOMERNAME = '" + cut(criteria.getCustomerNameEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getCustomerNameNotEquals())) {
            buf.append("    AND CUSTOMERNAME != '" + cut(criteria.getCustomerNameNotEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getCustomerNameLike())) {
            buf.append("    AND CUSTOMERNAME LIKE '" + cut(criteria.getCustomerNameLike()) + "'");
        }
        if(criteria.getCreateTimeUpper() != null) {
            buf.append("    AND CREATETIME <= " + criteria.getCreateTimeUpper());
        }
        if(criteria.getCreateTimeLower() != null) {
            buf.append("    AND CREATETIME >= " + criteria.getCreateTimeLower());
        }
        if(criteria.getCreateTimeEquals() != null) {
            buf.append("    AND CREATETIME = '" + criteria.getCreateTimeEquals() + "'");
        }
        if(criteria.getCreateTimeNotEquals() != null) {
            buf.append("    AND CREATETIME != '" + criteria.getCreateTimeNotEquals() + "'");
        }
        if (criteria.getPointsUpper() != null) {
            buf.append("    AND POINTS <= " + criteria.getPointsUpper());
        }
        if (criteria.getPointsLower() != null) {
            buf.append("    AND POINTS >= " + criteria.getPointsLower());
        }
        if (criteria.getPointsEquals() != null) {
            buf.append("    AND POINTS = '" + criteria.getPointsEquals() + "'");
        }
        if (criteria.getPointsNotEquals() != null) {
            buf.append("    AND POINTS != '" + criteria.getPointsNotEquals() + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getTypeEquals())) {
            buf.append("    AND TYPE = '" + cut(criteria.getTypeEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getTypeNotEquals())) {
            buf.append("    AND TYPE != '" + cut(criteria.getTypeNotEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getTypeLike())) {
            buf.append("    AND TYPE LIKE '" + cut(criteria.getTypeLike()) + "'");
        }
        if (!Strings.isNullOrEmpty(criteria.getDetailEquals())) {
            buf.append("    AND DETAIL = '" + cut(criteria.getDetailEquals()) + "'");
        }
        if (!Strings.isNullOrEmpty(criteria.getDetailNotEquals())) {
            buf.append("    AND DETAIL != '" + cut(criteria.getDetailNotEquals()) + "'");
        }
        if (!Strings.isNullOrEmpty(criteria.getDetailLike())) {
            buf.append("    AND DETAIL LIKE '" + cut(criteria.getDetailLike()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getActionEquals())) {
            buf.append("    AND ACTION = '" + cut(criteria.getActionEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getActionNotEquals())) {
            buf.append("    AND ACTION != '" + cut(criteria.getActionNotEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getActionLike())) {
            buf.append("    AND ACTION LIKE '" + cut(criteria.getActionLike()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getCustomerIdEquals())) {
            buf.append("    AND CUSTOMERID = '" + cut(criteria.getCustomerIdEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getCustomerIdNotEquals())) {
            buf.append("    AND CUSTOMERID != '" + cut(criteria.getCustomerIdNotEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getCustomerIdLike())) {
            buf.append("    AND CUSTOMERID LIKE '" + cut(criteria.getCustomerIdLike()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getPhoneEquals())) {
            buf.append("    AND PHONE = '" + cut(criteria.getPhoneEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getPhoneNotEquals())) {
            buf.append("    AND PHONE != '" + cut(criteria.getPhoneNotEquals()) + "'");
        }
        if(!Strings.isNullOrEmpty(criteria.getPhoneLike())) {
            buf.append("    AND PHONE LIKE '" + cut(criteria.getPhoneLike()) + "'");
        }
        if(criteria.getCustomerUIDEquals() != null) {
            buf.append("    AND CUSTOMERUID = '" + criteria.getCustomerUIDEquals() + "'");
        }
        if(criteria.getCustomerUIDNotEquals() != null) {
            buf.append("    AND CUSTOMERUID != '" + criteria.getCustomerUIDNotEquals() + "'");
        }
        if(sort != null && sort.getColumns().size() > 0) {
            buf.append(" ORDER BY ");
            sort.getColumns().forEach(c->buf.append(c.getColumnName().toUpperCase())
                .append(" ").append((c.getAscending() != null && c.getAscending()) ? "ASC" : "DESC")
                .append(", "));
            buf.append("RECORD_ID ASC");
        }
        return buf.toString();
    }
    
    @Override
    public <T extends Unit > String getUpdateStatement(T source) {
        AccumulateListTableBean data = null;
        
        if(source instanceof com.restaurant.application.indexes.accumulatelist.mysql.AccumulateListTableFromAccumulateIF) {
            data = new AccumulateListTableBean();
             ((com.restaurant.application.indexes.accumulatelist.mysql.AccumulateListTableFromAccumulateIF)source).getAccumulateDataForAccumulateListTable(data);
        }
        
        return data == null ? null: getLocalUpdateStatement(data);
    }
}
